package com.example.springboot.context;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.annotation.Configuration;

/**
 * FactoryBean扩展点
 * <p> Spring通过反射机制利用bean的class属性指定支线类去实例化bean，
 * 在某些情况下，实例化Bean过程比较复杂，如果按照传统的方式，则需要在bean中提供大量的配置信息。
 * 配置方式的灵活性是受限的，这时采用编码的方式可能会得到一个简单的方案。
 *
 * <p> Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口，
 * 用户可以通过实现该接口定制实例化Bean的逻辑。
 *
 * <p> FactoryBean接口对于Spring框架来说占用重要的地位，Spring自身就提供了70多个FactoryBean的实现。
 *      1. ProxyFactoryBean → AOP 代理对象 ;
 *      2. SqlSessionFactoryBean → MyBatis ;
 *      3. LocalSessionFactoryBean → Hibernate 。
 * <p> 可以将复杂逻辑隐藏在工厂内部，对外只暴露最终对象，给上层应用带来了便利。
 * <p> 从Spring3.0开始，FactoryBean开始支持泛型，即接口声明改为FactoryBean<T>的形式
 *
 * <p> 使用场景：用户可以扩展这个类，来为要实例化的bean作一个代理，
 * 比如为该对象的所有的方法作一个拦截，在调用前后输出一行log，模仿ProxyFactoryBean的功能。
 * <p>
 *
 * @author Zhang.Z
 * @version 2025-09-21
 */
@Configuration
public class Test11FactoryBean implements FactoryBean<Test11FactoryBean.TestFactoryInnerBean> {

    /**
     * 返回由 FactoryBean 创建的 Bean 实例
     */
    @Override
    public TestFactoryInnerBean getObject() throws Exception {
        System.out.println("test11 factory bean getObject");
        return new Test11FactoryBean.TestFactoryInnerBean();
    }

    /**
     * 返回创建的 Bean 的类型
     */
    @Override
    public Class<?> getObjectType() {
        System.out.println("test11 factory bean getObjectType");
        return Test11FactoryBean.TestFactoryInnerBean.class;
    }

    /**
     * 返回是否单例
     */
    @Override
    public boolean isSingleton() {
        return true;
    }

    public static class TestFactoryInnerBean {

    }
}
